local json=require("cocos.cocos2d.json")
local BgMapFloorTile = require("app.map.BgMapFloorTile")
local MapPoint = require("app.map.MapPoint")
local PortalSp = require("app.map.PortalSp")
--bg map class 背景地图类
local BgMap = class("BgMap",function()
    return display.newNode()
end)
BgMap.TYPE_PROTAL = 100
BgMap.TYPE_BORN_POINT = 101
BgMap.TYPE_NPC = 200

function BgMap:ctor(nMapID)
    self:init(nMapID)
end
--初始化变量
function BgMap:initVariable()
    self.m_gridRow = 0
    self.m_gridCol = 0
    self.m_gridSize = cc.size(0, 0)
    self.m_imageRow = 0 --cut image 切图
    self.m_imageCol = 0
    self.m_imageSize = cc.size(0, 0)
    self.m_bgSize = cc.size(0, 0)

    self.m_grid = {}--grid data 路径格子数据
        
    self.m_transPoints = {}
    self.m_bornPoint = {}
    self.m_npcInfos = {}

    self.m_floorTiles = {} --tile of map 动态载入和释放地图资源
end

-- 加载地图
function BgMap:init(nMapID)
    self:initVariable()
    self.m_nMapID = nMapID
    --读取格子数据
    self:readGirdData()
    --读取地图信息(born npc ..)
    self:readGoodsData()
    --载入切片的地图
    self:initBgMapFloorTile()
    --显示和隐藏屏幕中和屏幕外的地图
    self:updateImageDisplay()
    --绘制测试网格
    --self:drawMapGrid()    
end

--载入格子数据
function BgMap:readGirdData()
    local path = string.format("map/%d/mapdata.json", self.m_nMapID)
    local json_str = cc.FileUtils:getInstance():getStringFromFile(path)
    local json_value = json.decode(json_str)
    
    -- 地图宽高
    local width = json_value["mapW"]
    local height = json_value["mapH"]
    self.m_bgSize = cc.size(width, height)
    
    --格子大小
    local gWidth = json_value["mapGridW"]
    local gHeight = json_value["mapGridH"]
    self.m_gridSize = cc.size(gWidth, gHeight)

    MapPoint.setGridSize(self.m_gridSize)
    --格子行列数
    self.m_gridRow = math.ceil(width/self.m_gridSize.width)
    self.m_gridCol = math.ceil(height/self.m_gridSize.height)
    --初始化格子数据
    self:initGridData(json_value["mapFlagArr"])
    
    -- 切图宽高
    local iWidth = json_value["divideBlockW"]
    local iHeight = json_value["divideBlockH"]
    self.m_imageSize = cc.size(iWidth, iHeight)
    self.m_imageRow = math.ceil(width/self.m_imageSize.width)
    self.m_imageCol = math.ceil(height/self.m_imageSize.height)
end
--初始化格子数据
function BgMap:initGridData(girdData)  
    for i = 0, self.m_gridCol-1 do
        self.m_grid[i] = {}
    end
    
    for i = 0, #girdData-1 do
        local griddata = girdData[i+1]
        if bit.band(griddata,4) ~=0 then
            self.m_bornPoint = cc.p(math.floor(i/self.m_gridRow),math.floor(i%self.m_gridRow))
            griddata = bit.band(griddata,3)
        end
        self.m_grid[math.floor(i/self.m_gridRow)][i%self.m_gridRow] = griddata
    end
end

function BgMap:readGoodsData()
    local path = string.format("map/%d/npc.json", self.m_nMapID)
    local json_str = cc.FileUtils:getInstance():getStringFromFile(path)
    if json_str == "" then return end
    local json_value = json.decode(json_str)
        
    for i = 1, #json_value["items"] do
        local item = json_value["items"][i]
        
        local itemType = item["itemType"]
        if configData.cfg_deliver[itemType] then   -- 传送点
            local npc_id = item["itemSN"]
            local point = cc.p(item["itemPosX"], item["itemPosY"])

            local pSp = PortalSp.new()
            pSp:setPosition(point)
            self:addChild(pSp,BgMap.getZOrderZero(self)+1)

            --deliver id
            self.m_transPoints[itemType] = MapPoint.ccp2gridp(point)          
        else -- NPC
            local npc_id = item["itemSN"]
            local point = MapPoint.ccp2gridp(cc.p(item["itemPosX"], item["itemPosY"]))
            --deliver id
            self.m_npcInfos[npc_id] = point
        end
    end
end

function BgMap:initBgMapFloorTile()
    for i = 0, self.m_imageCol-1 do
        for j = 0, self.m_imageRow-1 do
            local floorTile = BgMapFloorTile.new()
            local path = string.format("map/%d/city%d_%d_%d.jpg", self.m_nMapID, self.m_nMapID, i, j)
            floorTile.m_fileName = path

            floorTile:setPosition(self.m_imageSize.width*j, self.m_imageSize.height*i)
            self:addChild(floorTile, BgMap.getZOrderZero(self)) -- z轴
            table.insert(self.m_floorTiles, floorTile)
        end
    end
end
--获取出生位置
function BgMap:getBornPosition()
    return self.m_bornPoint
end
function BgMap:checkDeliverGrid(mappoint)
    for k,v in pairs(self.m_transPoints) do
        return (v.x == mappoint.x and v.y == mappoint.z),k
    end
    return false
end

function BgMap.getZOrder(point)
    return (-point.y / 10.0)
end

function BgMap.getZOrderZero(bgMap)
    return (-bgMap.m_bgSize.height / 10.0)
end

function BgMap:updateImageDisplay()
    local rect = self:getShowRect()
    local rect2 = self:getHideRect()
    
    local nStartX = math.floor(rect.x / self.m_imageSize.width)
    local nStartY = math.floor(rect.y / self.m_imageSize.height)
    nStartX = math.max(nStartX, 0)
    nStartY = math.max(nStartY, 0)
    
    local nEndX = math.ceil((rect.x+rect.width) / self.m_imageSize.width)
    local nEndY = math.ceil((rect.y+rect.height) / self.m_imageSize.height)
    nEndX = math.min(nEndX, self.m_imageRow-1)
    nEndY = math.min(nEndY, self.m_imageCol-1)
    
    for i = nStartY, nEndY do
        for j = nStartX, nEndX do
            self.m_floorTiles[i*self.m_imageRow+j+1]:IntelligentDisplay(rect, rect2)
        end
    end
end

function BgMap:getCurrentGridValue(mpoint)
    local row = mpoint.x
    local col = mpoint.z
    local relust = 1
    
    if (1 < col and col < self.m_gridCol-1 and 1 < row and row < self.m_gridRow-1) then
        relust = self.m_grid[col][row]
    end
    
    return relust
end

function BgMap:getShowRect()   
    if (not self.m_tmpRect) then
        self.m_tmpRect = cc.rect(0, 0, 0, 0)
    end
        
    self.m_tmpRect.x = 0 - BgMapFloorTile.OFF_SIZE.x
    self.m_tmpRect.y = 0 - BgMapFloorTile.OFF_SIZE.y
    self.m_tmpRect.x = self.m_tmpRect.x - self:getPositionX()
    self.m_tmpRect.y = self.m_tmpRect.y - self:getPositionY()
    self.m_tmpRect.width = display.width + BgMapFloorTile.OFF_SIZE.x*2
    self.m_tmpRect.height = display.height + BgMapFloorTile.OFF_SIZE.y*2
    
    return self.m_tmpRect
end

function BgMap:getHideRect()
    if (not self.m_tmpRect) then
        self.m_tmpRect = cc.rect(0, 0, 0, 0)
    end

    self.m_tmpRect.x = 0 - BgMapFloorTile.OFF_SIZE.x * 2
    self.m_tmpRect.y = 0 - BgMapFloorTile.OFF_SIZE.y * 2
    self.m_tmpRect.x = self.m_tmpRect.x - self:getPositionX()
    self.m_tmpRect.y = self.m_tmpRect.y - self:getPositionY()
    self.m_tmpRect.width = display.width + BgMapFloorTile.OFF_SIZE.x*4
    self.m_tmpRect.height = display.height + BgMapFloorTile.OFF_SIZE.y*4
    return self.m_tmpRect    
end

function BgMap:getMapGrid()
    return self.m_grid
end

function BgMap:getGridRow()
    return self.m_gridRow
end

function BgMap:getGridCol()
    return self.m_gridCol
end

function BgMap:drawMapGrid()
    local drawNode = cc.DrawNode:create()
    local grid_size = MapPoint.GRID_SIZE
    self:addChild(drawNode, 10)
    local color = cc.c4f(1,1,1,1)
    for i=1,self.m_gridCol do
        drawNode:drawLine( cc.p(0, grid_size.height*(i-1)), cc.p(self.m_bgSize.width, grid_size.height*(i-1)), color)
    end
    for i=1,self.m_gridRow do
        drawNode:drawLine( cc.p(grid_size.width*(i-1),0), cc.p(grid_size.width*(i-1),self.m_bgSize.height), color)
    end
    self.drawNode = drawNode
end

function BgMap:setVisibleDrawNode(visible)
    if self.drawNode == nil then
        self:drawMapGrid()
    end
    self.drawNode:setVisible(visible)
end

return BgMap